﻿using System;
using System.Collections;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace MyLib.Web.UI {
	/// <summary>
	/// Allow multi checked items.
	/// </summary>
	public class MyCheckBoxList : CheckBoxList {
		/// <summary>
		/// 
		/// </summary>
		private const string MULTI_VALUE_SEPARATOR = ",";

		private string m_cachedSelectedValue;

		private int m_cachedSelectedIndex;

		/// <summary>
		/// 
		/// </summary>
		[Bindable(true, BindingDirection.TwoWay)]
		public override string SelectedValue {
			get {
				return string.Join(",", this.Items.Cast<ListItem>()
					.Where(_ => _.Selected)
					.Select(_ => _.Value));
			}
			set {
				if (this.Items.Count == 0) {
					m_cachedSelectedValue = value;
					return;
				}

				if ((value == null) || (base.DesignMode && (value.Length == 0))) {
					this.ClearSelection();
					return;
				}

				SetSelectedValue(value);

				m_cachedSelectedValue = value;
			}
		} // end of SelectedValue.

		/// <summary>
		/// 
		/// </summary>
		/// <param name="value"></param>
		protected virtual void SetSelectedValue(string value) {
			var values = value.Split(new string[] { MULTI_VALUE_SEPARATOR }, StringSplitOptions.None);

			if (values != null && values.Length != 0) {
				this.ClearSelection();

				foreach (ListItem item in this.Items) {
					item.Selected = values.Contains(item.Value);
				}
			}
		} // end of SetSelectedValue.

		/// <summary>
		/// 
		/// </summary>
		[Bindable(true, BindingDirection.TwoWay)]
		public override int SelectedIndex {
			get {
				return base.SelectedIndex;
			}
			set {
				base.SelectedIndex = value;
				m_cachedSelectedIndex = value;
			}
		} // end of SelectedIndex.

		/// <summary>
		/// 
		/// </summary>
		/// <param name="dataSource"></param>
		protected override void PerformDataBinding(IEnumerable dataSource) {
			if (dataSource != null) {
				bool flag = false;
				bool flag2 = false;
				string dataTextField = this.DataTextField;
				string dataValueField = this.DataValueField;
				string dataTextFormatString = this.DataTextFormatString;
				if (!this.AppendDataBoundItems) {
					this.Items.Clear();
				}
				ICollection is2 = dataSource as ICollection;
				if (is2 != null) {
					this.Items.Capacity = is2.Count + this.Items.Count;
				}
				if ((dataTextField.Length != 0) || (dataValueField.Length != 0)) {
					flag = true;
				}
				if (dataTextFormatString.Length != 0) {
					flag2 = true;
				}
				foreach (object obj2 in dataSource) {
					ListItem item = new ListItem();
					if (flag) {
						if (dataTextField.Length > 0) {
							item.Text = DataBinder.GetPropertyValue(obj2, dataTextField, dataTextFormatString);
						}
						if (dataValueField.Length > 0) {
							item.Value = DataBinder.GetPropertyValue(obj2, dataValueField, null);
						}
					} else {
						if (flag2) {
							item.Text = string.Format(CultureInfo.CurrentCulture, dataTextFormatString, new object[] { obj2 });
						} else {
							item.Text = obj2.ToString();
						}
						item.Value = obj2.ToString();
					}
					this.Items.Add(item);
				}
			}
			if (this.m_cachedSelectedValue != null) {
				SetSelectedValue(this.m_cachedSelectedValue);
			} else if (this.m_cachedSelectedIndex != -1) {
				this.SelectedIndex = this.m_cachedSelectedIndex;
				this.m_cachedSelectedIndex = -1;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="postDataKey"></param>
		/// <param name="postCollection"></param>
		/// <returns></returns>
		protected override bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection) {
			var hasChanged = false;

			if (base.IsEnabled) {
				string prefix = postDataKey.Substring(0, this.UniqueID.Length + 1);

				this.EnsureDataBound();

				var tkey = postDataKey.Substring(this.UniqueID.Length + 1);
				var p0 = tkey.LastIndexOf('_');
				if (p0 != -1)
					tkey = tkey.Substring(p0 + 1);

				var n0 = int.Parse(tkey, CultureInfo.InvariantCulture);

				if ((n0 >= 0) && (n0 < Items.Count)) {
					var item = this.Items[n0];
					if (!item.Enabled) {
						return hasChanged;
					}

					bool flag = postCollection[postDataKey] != null;
					if (item.Selected != flag) {
						item.Selected = flag;

						hasChanged = true;
						return hasChanged;
					}
				}
			}

			return hasChanged;
		} // end of LoadPostData.

		/// <summary>
		/// 
		/// </summary>
		public MyCheckBoxList() {
			m_cachedSelectedValue = null;
			m_cachedSelectedIndex = -1;
		}
	} // end of MyCheckBoxList.
}
